﻿using System;
using System.Linq.Expressions;

namespace IInject.Registration
{
	/// <summary>
	/// A class that provides methods for building
	/// and registering <see cref="RegistryContext"/>s.
	/// </summary>
	/// <typeparam name="T"></typeparam>
	public class GenericContextBuilder<T> : DefaultContextBuilder, IContextBuilder<T>
	{
		/// <summary>
		/// 
		/// </summary>
		/// <param name="container"></param>
		public GenericContextBuilder(IContainer container) : base(typeof(T), container)
		{
		}

		/// <summary>
		/// 
		/// </summary>
		/// <typeparam name="TTo"></typeparam>
		/// <returns></returns>
		public IContextBuilder<T> To<TTo>() where TTo : T
		{
			return (IContextBuilder<T>)To(typeof(TTo));
		}

		/// <summary>
		/// Registers the selected property to be injected.
		/// </summary>
		/// <param name="propExpression">The Func{T, object} used to select the property.</param>
		///<returns>The current <see cref="IContextBuilder"/>.</returns>
		public IContextBuilder<T> Inject(Expression<Func<T, object>> propExpression)
		{
			return (IContextBuilder<T>)Inject<T>(propExpression);
		}

		/// <summary>
		/// Registers the selected property to be injected with the provided value.
		/// </summary>
		/// <typeparam name="TProperty">The type of property returned from the expression.</typeparam>
		/// <param name="propExpression">The Func{T, object} used to select the property.</param>
		/// <param name="value">The value to be injected into the property.</param>
		///<returns>The current <see cref="IContextBuilder{T}"/>.</returns>
		public IContextBuilder<T> Inject<TProperty>(Expression<Func<T, TProperty>> propExpression, TProperty value)
		{
			VisitExpression(propExpression);

			if (Properties.Count > 0)
			{
				Properties[Properties.Count - 1].Value = value;
			}

			return this;
		}
	}
}
